// $Id: uuid_ptr.cpp 2 2009-09-02 08:47:42Z joseph2002 $
/*
 * Copyright 2009 Joseph Wu
 * Distributed under the Boost Software License, Version 1.0.
 * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
 *
 * For more information, see http://xpcomplus.sourceforge.net
 */

#include <boost/test/unit_test.hpp>
#include <xpcom/memory.hpp>
#include <xpcom/impl/uuid_ptr.hpp>

namespace xpcom {
namespace {

const uuid s_id1 = uuid::nil;
const uuid s_id2 = { 0x64D47515, 0xADE3, 0xa5d1, { 0xAB, 0xAE, 0x3A, 0x93, 0x62, 0xC5, 0xA5, 0x51 } };
const uuid s_id3 = { 0x66666666, 0xADE3, 0xa5d1, { 0xAB, 0xAE, 0x3A, 0x93, 0x62, 0xC5, 0xA5, 0x51 } };

void do_out_impl_1(uuid& u)
{
    BOOST_CHECK(u.is_nil());
    u = uuid::nil;
}

void do_out_1(uuid** u)
{
    do_out_impl_1(impl::uuid_ptr_out(u));
}

void do_out_impl_2(uuid& u)
{
    BOOST_CHECK(u.is_nil());
    u = s_id1;
}

void do_out_2(uuid** u)
{
    do_out_impl_2(impl::uuid_ptr_out(u));
}

void do_out_impl_3(uuid& u)
{
    BOOST_CHECK(u.is_nil());
    u = s_id2;
}

void do_out_3(uuid** u)
{
    do_out_impl_3(impl::uuid_ptr_out(u));
}

uuid do_out_impl_retval()
{
    uuid u = s_id3;
    return u;
}

void do_out_retval(uuid** u)
{
    impl::uuid_ptr_out retval(u);
    retval = do_out_impl_retval();
}

void do_inout_impl_1(uuid& u)
{
    BOOST_CHECK(u == s_id2);
    u = uuid::nil;
}

void do_inout_1(uuid** u)
{
    do_inout_impl_1(impl::uuid_ptr_inout(u));
}

void do_inout_impl_2(uuid& u)
{
    BOOST_CHECK(u == s_id2);
    u = s_id3;
}

void do_inout_2(uuid** u)
{
    do_inout_impl_2(impl::uuid_ptr_inout(u));
}

void do_inout_impl_3(uuid& u)
{
    BOOST_CHECK(u.is_nil());
    u = s_id2;
}

void do_inout_3(uuid** u)
{
    do_inout_impl_3(impl::uuid_ptr_inout(u));
}

}
}

BOOST_AUTO_TEST_CASE(test_uuid_ptr_in)
{
    using namespace xpcom;

    uuid id1 = s_id1;
    uuid id2 = s_id2;

    BOOST_CHECK(impl::uuid_ptr_in(&id1) == id1);
    BOOST_CHECK(impl::uuid_ptr_in(0) == uuid::nil);
    BOOST_CHECK(impl::uuid_ptr_in(&id2) == id2);
    BOOST_CHECK(&impl::uuid_ptr_in(&id2) == &id2);
}

BOOST_AUTO_TEST_CASE(test_uuid_ptr_out)
{
    using namespace xpcom;

    uuid* id;
    do_out_1(&id);
    BOOST_CHECK(id == 0);

    do_out_2(&id);
    BOOST_CHECK(id == 0);

    do_out_3(&id);
    BOOST_CHECK(*id == s_id2);
    memory::free(id);

    do_out_retval(&id);
    BOOST_CHECK(*id == s_id3);
    memory::free(id);
}

BOOST_AUTO_TEST_CASE(test_uuid_ptr_inout)
{
    using namespace xpcom;

    uuid* id;

    id = ::new(mem) uuid(s_id2);
    do_inout_1(&id);
    BOOST_CHECK(id == 0);

    id = ::new(mem) uuid(s_id2);
    do_inout_2(&id);
    BOOST_CHECK(*id == s_id3);
    memory::free(id);

    id = 0;
    do_inout_3(&id);
    BOOST_CHECK(*id == s_id2);
    memory::free(id);
}
